package com.mikao.service.impl;

import com.mikao.constant.ErrorCode;
import com.mikao.dao.*;
import com.mikao.dto.bo.*;
import com.mikao.dto.vo.*;
import com.mikao.entity.*;
import com.mikao.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.persistence.criteria.Predicate;
import javax.transaction.Transactional;
import java.util.*;

/**
 * @author kenny
 */

@Slf4j
@Service
public class GoodsServiceImpl implements GoodsService {

    private GoodsDao goodsDao;
    private EvaluateDao evaluateDao;
    private UserDao userDao;
    private TicketDao ticketDao;
    private BuyCarDao buyCarDao;
    private AddressDao addressDao;
    private UserTicketDao userTicketDao;
    private OrderDao orderDao;
    private UserPointDao userPointDao;
    private GoodsEvaluateDao goodsEvaluateDao;
    private MoneyDetailDao moneyDetailDao;
    private UserSellOrderDao userSellOrderDao;
    private PreTradeDao preTradeDao;
    public GoodsServiceImpl(GoodsDao goodsDao, EvaluateDao evaluateDao, UserDao userDao, TicketDao ticketDao, BuyCarDao buyCarDao, AddressDao addressDao, UserTicketDao userTicketDao, OrderDao orderDao, UserPointDao userPointDao, GoodsEvaluateDao goodsEvaluateDao, MoneyDetailDao moneyDetailDao, UserSellOrderDao userSellOrderDao, PreTradeDao preTradeDao) {
        this.goodsDao = goodsDao;
        this.evaluateDao = evaluateDao;
        this.userDao = userDao;
        this.ticketDao = ticketDao;
        this.buyCarDao = buyCarDao;
        this.addressDao = addressDao;
        this.userTicketDao = userTicketDao;
        this.orderDao = orderDao;
        this.userPointDao = userPointDao;
        this.goodsEvaluateDao = goodsEvaluateDao;
        this.moneyDetailDao = moneyDetailDao;
        this.userSellOrderDao = userSellOrderDao;
        this.preTradeDao = preTradeDao;
    }

    @Override
    public BaseResult<List<GoodsDto>> goodsList(Date createTime, int size, Long type, String order, Integer from) {
        List<GoodsDto> dtos = new ArrayList<>();
        GoodsDto goodsDto;

        Page<Goods> pages = goodsDao.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            Predicate predicate1 = criteriaBuilder.equal(root.get("status").as(Boolean.class), true);
            Predicate predicate3;
            Predicate predicate2 = null;
            if (ObjectUtils.isEmpty(createTime)) {
                predicate3 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), new Date());
            } else {
                predicate3 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), createTime);
            }
            Predicate predicate4 = criteriaBuilder.equal(root.get("type").as(Long.class), type);
            if (type == 4) {
                Predicate predicate5 = criteriaBuilder.equal(root.get("isPoint").as(Boolean.class), false);
                predicates.add(predicate5);
            }
            if (!ObjectUtils.isEmpty(from)) {
                predicate2 = criteriaBuilder.equal(root.get("source").as(Integer.class), from);
            }

            predicates.add(predicate1);
            predicates.add(predicate2);
            predicates.add(predicate3);
            predicates.add(predicate4);
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, new PageRequest(0, size, new Sort(Sort.Direction.DESC, "createTime")));

        for (Goods goods : pages.getContent()) {
            goodsDto = new GoodsDto();
            BeanUtils.copyProperties(goods, goodsDto);
            dtos.add(goodsDto);
        }

        if ("2".equals(order)) {
            log.info("销量倒序");
            dtos.sort((o1, o2) -> o2.getSaledNum().compareTo(o1.getSaledNum()));
        }
        if ("3".equals(order)) {
            log.info("销量正序");
            dtos.sort(Comparator.comparing(GoodsDto::getSaledNum));
        }
        if ("4".equals(order)) {
            log.info("价格正序");
            dtos.sort(Comparator.comparing(GoodsDto::getPrice));
        }
        if ("5".equals(order)) {
            log.info("价格倒序");
            dtos.sort((o1, o2) -> o2.getPrice().compareTo(o1.getPrice()));
        }
        if ("6".equals(order)) {
            log.info("时间正序");
            dtos.sort(Comparator.comparing(GoodsDto::getCreateTime));
        }
        return new BaseResult<>(dtos);
    }

    @Override
    public BaseResult<GoodsDetailDto> goodsDetail(Long id) {
        GoodsDetailDto detailDto = new GoodsDetailDto();

        Goods goods = goodsDao.findOne(id);
        if (!ObjectUtils.isEmpty(goods)) {
            BeanUtils.copyProperties(goods, detailDto);
            String[] split = goods.getImages().split(",");
            detailDto.setImages(split);

            /*
             * 商品评价
             */
            List<GoodsEvaluate> list = evaluateDao.findAllByGoodsIdOrderByCreateTimeDesc(id);
            List<EvaluateDto> dtos = new ArrayList<>();
            EvaluateDto dto;
            for (GoodsEvaluate evaluate : list) {
                dto = new EvaluateDto();
                BeanUtils.copyProperties(evaluate, dto);
                User user = userDao.findOne(evaluate.getUserId());
                if (!ObjectUtils.isEmpty(user)) {
                    dto.setImageUrl(user.getImageUrl());
                    dto.setNickname(user.getName());
                }
                dtos.add(dto);
                break;
            }
            detailDto.setEvaluates(dtos);

            /*
             * 优惠券
             */
            List<Ticket> all = ticketDao.findAll();
            List<TicketDto> ticketDtos = new ArrayList<>();
            TicketDto ticketDto;
            for (Ticket ticket : all) {
                ticketDto = new TicketDto();
                BeanUtils.copyProperties(ticket, ticketDto);
                ticketDtos.add(ticketDto);
            }
            detailDto.setTickets(ticketDtos);

        }
        return new BaseResult<>(detailDto);
    }

    @Override
    public BaseResult addCar(Long userId, CarForm carForm) {
        User user = userDao.findOne(userId);
        if (!ObjectUtils.isEmpty(user)) {
            BuyCar car = buyCarDao.findAllByGoodsIdAndUserId(carForm.getGoodsId(), userId);
            if (ObjectUtils.isEmpty(car)) {
                BuyCar buyCar = new BuyCar();
                buyCar.setUserId(userId);
                buyCar.setGoodsId(carForm.getGoodsId());
                buyCar.setNum(carForm.getNum());
                buyCarDao.saveAndFlush(buyCar);
            } else {
                car.setNum(carForm.getNum());
                buyCarDao.saveAndFlush(car);
            }
            return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
        } else {
            return new BaseResult(ErrorCode.USER_NOT_EXIT.getCode(), ErrorCode.USER_NOT_EXIT.getMsg());
        }
    }

    @Override
    public BaseResult<UserPointGoodsDto> pointGoodsList(Long userId) {
        UserPointGoodsDto userPointGoodsDto = new UserPointGoodsDto();
        User user = userDao.findOne(userId);
        if (!ObjectUtils.isEmpty(user)) {
            userPointGoodsDto.setPoint(user.getPoint());
        }

        List<PointGoodsDto> dtos = new ArrayList<>();
        PointGoodsDto dto;

        List<Goods> list = goodsDao.findAllByIsPointOrderByCreateTimeDesc(true);
        for (Goods goods : list) {
            dto = new PointGoodsDto();
            BeanUtils.copyProperties(goods, dto);
            dtos.add(dto);
        }

        userPointGoodsDto.setDtos(dtos);
        return new BaseResult<>(userPointGoodsDto);
    }

    @Override
    public BaseResult<List<TicketDto>> ticketList(Long userId, Boolean status) {
        List<UserTicket> list = userTicketDao.findAllByUserIdAndStatus(userId, status);
        List<TicketDto> dtos = new ArrayList<>();
        TicketDto dto;
        for (UserTicket userTicket : list) {
            Ticket ticket = ticketDao.findOne(userTicket.getTicketId());
            if (!ObjectUtils.isEmpty(ticket)) {
                dto = new TicketDto();
                BeanUtils.copyProperties(ticket, dto);
                dto.setStatus(userTicket.getStatus());
                dtos.add(dto);
            }
        }
        return new BaseResult<>(dtos);
    }

    @Override
    public BaseResult<SureOrderDto> sureOrder(Long userId, Long id) {
        SureOrderDto dto = new SureOrderDto();
        String address = "";
        String receiverName = "";
        String receiverPhone = "";
        if (!ObjectUtils.isEmpty(userId)) {

            /*
             * 设置收货地址
             */
            List<Address> addresses = addressDao.findAllByUserIdAndIsSelected(userId, true);
            if (!ObjectUtils.isEmpty(addresses)) {
                Address aa = addresses.get(0);
                address = aa.getProvince() + aa.getCity() + aa.getArea() + aa.getAddress() + aa.getAddress();
                receiverName = aa.getReceiverName();
                receiverPhone = aa.getReceiverPhone();
                dto.setReceiverName(receiverName);
                dto.setReceiverPhone(receiverPhone);
                dto.setAddressId(aa.getId());
            }
            dto.setAddress(address);
            dto.setReceiverPhone(receiverPhone);
            dto.setReceiverName(receiverName);

            /*
             * 设置商品缩略信息
             */
            Goods goods = goodsDao.findOne(id);
            if (!ObjectUtils.isEmpty(goods)) {
                BeanUtils.copyProperties(goods, dto);
                dto.setGoodsId(id);
            }

            /*
             *  设置匹配优惠券
             */
            Integer price = Integer.valueOf(goods.getPrice());
            List<UserTicket> list = userTicketDao.findAllByUserIdAndStatus(userId, false);
            if (ObjectUtils.isEmpty(list)) {
                dto.setTicket(0);
            }
            List<Integer> tt = new ArrayList<>();
            for (UserTicket userTicket : list) {
                Ticket one = ticketDao.findOne(userTicket.getTicketId());
                if (!ObjectUtils.isEmpty(one)) {
                    tt.add(one.getSuitPrice());
                    Integer max = Collections.max(tt);
                    if (price > max && one.getSuitPrice() >= max) {
                        dto.setTicketId(one.getId());
                        dto.setTicket(one.getPrice());
                    }
                }
            }

        }
        return new BaseResult<>(dto);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public BaseResult submitOrder(Long userId, SubmitOrderForm submitOrderForm) {
        Goods goods = goodsDao.findOne(submitOrderForm.getGoodsId());
        if (!ObjectUtils.isEmpty(goods)) {
            if (goods.getType() == 4) {
                /*
                 * 生成待付款订单,只有商品类型为果实才会生成待付款订单
                 */
                Orders orders = new Orders();
                orders.setUserId(userId);
                BeanUtils.copyProperties(submitOrderForm, orders);
                orders.setType(1);
                orderDao.saveAndFlush(orders);

                /*
                 * 让优惠券失效
                 */
                if (!ObjectUtils.isEmpty(submitOrderForm.getTicketId())) {
                    UserTicket ticket = userTicketDao.findOne(submitOrderForm.getTicketId());
                    if (!ObjectUtils.isEmpty(ticket)) {
                        ticket.setStatus(true);
                        userTicketDao.saveAndFlush(ticket);
                    }
                }
                return new BaseResult(orders.getId());
            }
            //如果为树苗或果树，则生成树苗和果树的待付款订单
            if (goods.getType() == 5 || goods.getType() == 2) {
                UserSellOrder sellOrder = new UserSellOrder();
                sellOrder.setGoodsId(submitOrderForm.getGoodsId());
                sellOrder.setUserId(userId);
                sellOrder.setType(1);
                sellOrder.setStatus(6);
                sellOrder.setIsPayed(false);
                userSellOrderDao.saveAndFlush(sellOrder);

                if (!ObjectUtils.isEmpty(submitOrderForm.getTicketId())) {
                    UserTicket ticket = userTicketDao.findOne(submitOrderForm.getTicketId());
                    if (!ObjectUtils.isEmpty(ticket)) {
                        ticket.setStatus(true);
                        userTicketDao.saveAndFlush(ticket);
                    }
                }
                return new BaseResult(sellOrder.getId());
            }
        }
        return null;
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public BaseResult submitPoint(Long userId, SubmitPointForm submitPointForm) {
        Goods goods = goodsDao.findOne(submitPointForm.getGoodsId());
        if (ObjectUtils.isEmpty(goods)) {
            return new BaseResult(ErrorCode.NULL_CONTENT.getCode(), "此商品已删除或已下架");
        }
        if (!goods.getIsPoint()) {
            return new BaseResult(ErrorCode.PARAM_ERROR.getCode(), "此商品不为积分商品");
        }
        User user = userDao.findOne(userId);
        if (!ObjectUtils.isEmpty(user) && user.getPoint() < goods.getPoint()) {
            return new BaseResult(ErrorCode.POINT_NOT_ENOUGH.getCode(), ErrorCode.POINT_NOT_ENOUGH.getMsg());
        }
        /*
         * 用户减积分
         */
        user.setPoint(user.getPoint() - goods.getPoint());

        /*
         * 生成新订单
         */
        Orders orders = new Orders();
        orders.setUserId(userId);
        orders.setGoodsId(submitPointForm.getGoodsId());
        orders.setAddressId(submitPointForm.getAddressId());
        orders.setType(2);
        orderDao.saveAndFlush(orders);

        /*
         * 生成积分消费记录
         */
        UserPoint userPoint = new UserPoint();
        userPoint.setPoint(goods.getPoint());
        userPoint.setType(0);
        userPoint.setUserId(userId);
        userPoint.setExplains("积分商品购买");
        userPointDao.saveAndFlush(userPoint);
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public BaseResult removeCar(Long userId, CarForm carForm) {
        BuyCar car = buyCarDao.findAllByGoodsIdAndUserId(carForm.getGoodsId(), userId);
        buyCarDao.delete(car);
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    public BaseResult<List<TicketDto>> ticket() {
        List<Ticket> all = ticketDao.findAll();
        List<TicketDto> dtos = new ArrayList<>();
        TicketDto dto;
        for (Ticket ticket : all) {
            dto = new TicketDto();
            BeanUtils.copyProperties(ticket, dto);
            dtos.add(dto);
        }
        return new BaseResult<>(dtos);
    }

    @Override
    public BaseResult<List<CarDto>> carList(Long userId) {
        List<CarDto> dtos = new ArrayList<>();
        CarDto dto;
        List<BuyCar> list = buyCarDao.findAllByUserIdOrderByCreateTimeDesc(userId);
        for (BuyCar buyCar : list) {
            dto = new CarDto();
            dto.setNum(buyCar.getNum());
            Goods one = goodsDao.findOne(buyCar.getGoodsId());
            if (!ObjectUtils.isEmpty(one)) {
                BeanUtils.copyProperties(one, dto);
                dto.setGoodsId(one.getId());
                dtos.add(dto);
            }
        }
        return new BaseResult<>(dtos);
    }

    @Override
    public BaseResult<List<DiscountDto>> dicountList(Date createTime, int size) {
        List<DiscountDto> dtos = new ArrayList<>();
        DiscountDto dto;

        Page<Goods> pages = goodsDao.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            Predicate predicate1 = criteriaBuilder.equal(root.get("status").as(Boolean.class), true);
            Predicate predicate2;

            if (ObjectUtils.isEmpty(createTime)) {
                predicate2 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), new Date());
            } else {
                predicate2 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), createTime);
            }
            Predicate predicate3 = criteriaBuilder.equal(root.get("isDiscount").as(Boolean.class), true);

            predicates.add(predicate1);
            predicates.add(predicate2);
            predicates.add(predicate3);
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, new PageRequest(0, size, new Sort(Sort.Direction.DESC, "createTime")));

        for (Goods goods : pages.getContent()) {
            dto = new DiscountDto();
            BeanUtils.copyProperties(goods, dto);
            dtos.add(dto);
        }

        return new BaseResult<>(dtos);
    }

    @Override
    public BaseResult deleteOrder(DeleteOrderForm deleteOrderForm) {
        orderDao.delete(deleteOrderForm.getOrderId());
        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    public BaseResult evaluate(Long userId, EvaluateForm evaluateForm) {
        //添加评价记录
        GoodsEvaluate evaluate;
        evaluate = goodsEvaluateDao.findAllByUserIdAndGoodsIdOrderByCreateTimeDesc(userId, evaluateForm.getGoodsId());
        if (!ObjectUtils.isEmpty(evaluate)) {
            return new BaseResult(ErrorCode.PARAM_ERROR.getCode(), "评价已存在");
        }
        BeanUtils.copyProperties(evaluateForm, evaluate);
        goodsEvaluateDao.saveAndFlush(evaluate);

        //修改订单状态
        Orders orders = orderDao.findOne(evaluateForm.getOrderId());
        if (!ObjectUtils.isEmpty(orders)) {
            orders.setType(5);
            orderDao.saveAndFlush(orders);
        }

        return new BaseResult(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public void doWxTreeTrade(String out_trade_no, String total_amount) {
        //修改订单状态
        UserSellOrder sellOrder = userSellOrderDao.findOne(Long.valueOf(out_trade_no));
        if (!ObjectUtils.isEmpty(sellOrder)) {
            sellOrder.setIsPayed(true);
            userSellOrderDao.saveAndFlush(sellOrder);
        }

        //生成消费明细
        MoneyDetail detail = new MoneyDetail();
        detail.setType(1);
        detail.setMoney(Double.valueOf(total_amount)/100);
        detail.setIntroduce("购买树类商品");
        detail.setUserId(sellOrder.getUserId());
        moneyDetailDao.saveAndFlush(detail);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public void doWxTrade(String out_trade_no, String total_amount) {
        log.info("----微信业务开始----");
        log.info(out_trade_no);
        log.info(total_amount);
        //修改订单状态

        Orders orders = orderDao.findOne(Long.valueOf((out_trade_no.substring(0,out_trade_no.length()-10))));
        if (!ObjectUtils.isEmpty(orders)) {
            orders.setType(2);
            orders.setPayType(1);
            orders.setTotalMoney(Double.valueOf(total_amount) / 100);
            orderDao.saveAndFlush(orders);
        }

        //生成消费明细
        MoneyDetail detail = new MoneyDetail();
        detail.setType(1);
        detail.setMoney(Double.valueOf(total_amount) / 100);
        detail.setIntroduce("购买果实类商品");
        detail.setUserId(orders.getUserId());
        moneyDetailDao.saveAndFlush(detail);
        log.info("----微信业务结束----");
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public void doAliTrade(String out_trade_no, String total_amount) {
        PreTrade preTrade = preTradeDao.findByOutTradeNo(out_trade_no);
        //存在预付订单 是支付宝支付 且 金额相等 且 没有被处理过
        if (!ObjectUtils.isEmpty(preTrade) && Double.doubleToLongBits(Double.valueOf(total_amount)) == Double.doubleToLongBits(preTrade.getAmount()) && !preTrade.getStatus()&&preTrade.getPlatform()==2) {

            log.info("存在待处理订单");
            //余额充值
            if (preTrade.getType() == 1) {
                //修改订单状态
                Orders orders = orderDao.findOne(Long.valueOf((out_trade_no)));
                if (!ObjectUtils.isEmpty(orders)) {
                    orders.setType(2);
                    orders.setPayType(2);
                    orders.setTotalMoney(Double.valueOf(total_amount));
                    orderDao.saveAndFlush(orders);
                }

                //生成消费明细
                MoneyDetail detail = new MoneyDetail();
                detail.setType(1);
                detail.setMoney(Double.valueOf(total_amount));
                detail.setIntroduce("购买果实类商品");
                detail.setUserId(orders.getUserId());
                moneyDetailDao.saveAndFlush(detail);
            }else if(preTrade.getType() == 2){
                log.info("执行充值");
                User user = userDao.findOne(preTrade.getBalanceId());
                user.setMoney(user.getMoney() + Double.valueOf(total_amount));
                userDao.saveAndFlush(user);
                //生成收入明细
                MoneyDetail detail = new MoneyDetail();
                detail.setType(2);
                detail.setMoney(Double.valueOf(total_amount));
                detail.setIntroduce("充值");
                detail.setUserId(preTrade.getBalanceId());
                moneyDetailDao.saveAndFlush(detail);

            }else{
                //修改订单状态
                UserSellOrder sellOrder = userSellOrderDao.findOne(Long.valueOf(out_trade_no.substring(0,out_trade_no.length()-10)));
                if (!ObjectUtils.isEmpty(sellOrder)) {
                    sellOrder.setIsPayed(true);
                    userSellOrderDao.saveAndFlush(sellOrder);
                }

                //生成消费明细
                MoneyDetail detail = new MoneyDetail();
                detail.setType(1);
                detail.setMoney(Double.valueOf(total_amount));
                detail.setIntroduce("购买树类商品");
                detail.setUserId(sellOrder.getUserId());
                moneyDetailDao.saveAndFlush(detail);
            }
        }
        preTrade.setStatus(true);
        preTradeDao.saveAndFlush(preTrade);

    }

    @Override
    public BaseResult<EvaluateDtos> evaluateList(Date createTime, int size, Long goodsId) {
        EvaluateDtos evaluateDtos = new EvaluateDtos();
        List<EvaluateDto> dtos = new ArrayList<>();
        EvaluateDto dto;

        Page<GoodsEvaluate> pages = goodsEvaluateDao.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            Predicate predicate1;
            if (ObjectUtils.isEmpty(createTime)) {
                predicate1 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), new Date());
            } else {
                predicate1 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), createTime);
            }
            Predicate predicate2 = criteriaBuilder.equal(root.get("goodsId").as(Long.class), goodsId);

            predicates.add(predicate1);
            predicates.add(predicate2);
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, new PageRequest(0, size, new Sort(Sort.Direction.DESC, "createTime")));

        System.out.println(pages);
        User user;
        for (GoodsEvaluate evaluate : pages.getContent()) {
            dto = new EvaluateDto();
            BeanUtils.copyProperties(evaluate, dto);
            user = userDao.findOne(evaluate.getUserId());
            if (!ObjectUtils.isEmpty(user)) {
                dto.setNickname(user.getName());
                dto.setImageUrl(user.getImageUrl());
                dtos.add(dto);
            }
        }

        Integer allCount = evaluateDao.findAllCount();
        Integer good = evaluateDao.findGoodCount();

        evaluateDtos.setGoodsRate("0");
        if (allCount != 0) {
            evaluateDtos.setGoodsRate(String.valueOf(good * 1.0 / allCount * 1.0));
        }
        evaluateDtos.setGoodsNum(good);
        evaluateDtos.setEvaluates(dtos);

        return new BaseResult<>(evaluateDtos);
    }

    @Override
    public BaseResult<List<GoodsSeach>> searchGoods(String name, Date createTime, int size) {
        List<GoodsSeach> dtos = new ArrayList<>();
        GoodsSeach dto;

        Page<Goods> pages = goodsDao.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            Predicate predicate1;
            if (ObjectUtils.isEmpty(createTime)) {
                predicate1 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), new Date());
            } else {
                predicate1 = criteriaBuilder.lessThan(root.get("createTime").as(Date.class), createTime);
            }
            Predicate predicate2 = criteriaBuilder.equal(root.get("status").as(Boolean.class), true);
            Predicate predicate3 = criteriaBuilder.like(root.get("introduce"), "%" + name + "%");

            predicates.add(predicate1);
            predicates.add(predicate2);
            predicates.add(predicate3);
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, new PageRequest(0, size, new Sort(Sort.Direction.DESC, "createTime")));

        for (Goods goods : pages.getContent()) {
            dto = new GoodsSeach();
            BeanUtils.copyProperties(goods, dto);
            dtos.add(dto);
        }
        return new BaseResult<>(dtos);
    }
}
